package cc.mrbird.febs.system.service.impl;

import cc.mrbird.febs.common.authentication.JWTUtil;
import cc.mrbird.febs.common.domain.QueryRequest;
import cc.mrbird.febs.common.exception.FebsException;
import cc.mrbird.febs.common.utils.SortUtil;
import cc.mrbird.febs.system.dao.*;
import cc.mrbird.febs.system.domain.*;
import cc.mrbird.febs.system.manager.TempInfoManager;
import cc.mrbird.febs.system.service.ITResidentHouseService;
import cc.mrbird.febs.system.service.ITResidentService;
import cc.mrbird.febs.system.vo.TResidentExcelVO;
import cc.mrbird.febs.system.vo.TResidentImportVO;
import cc.mrbird.febs.system.vo.TResidentVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.ImmutableMap;
import com.wuwenze.poi.pojo.ExcelErrorField;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jetbrains.annotations.Nullable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author dtwei
 */
@Service
public class TResidentServiceImpl extends ServiceImpl<TResidentMapper, TResident> implements ITResidentService {

    @Resource
    private ITResidentHouseService itResidentHouseService;

    @Resource
    private TempInfoManager tempInfoManager;

    @Resource
    private TResidentMapper tResidentMapper;

    @Resource
    private THouseMapper tHouseMapper;

    @Resource
    private TResidentHouseMapper tResidentHouseMapper;

    @Resource
    private TAreaManagerMapper tAreaManagerMapper;

    @Resource
    private TShopMapper tShopMapper;

    @Override
    public IPage<TResidentVO> findResidentPage(TResident rs, String areaName, QueryRequest request) {
        try {
            Page<TResident> page = new Page<>();
            SortUtil.handlePageSort(request, page, true);
            return this.baseMapper.findRSDetails(page, rs, areaName);
        } catch (Exception e) {
            log.error("获取店铺信息失败", e);
            return null;
        }
    }

    @Override
    public void createRs(TResident rs) throws Exception {
        //获取当前用户
        String token = (String) SecurityUtils.getSubject().getPrincipal();
        String username = "";
        String userId = "";
        if (StringUtils.isNotBlank(token)) {
            username = JWTUtil.getUsername(token);
            userId = JWTUtil.getUserId(token);
        }

        LambdaQueryWrapper<TResident> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TResident::getCardId, rs.getCardId());
        List<TResident> dupRs = baseMapper.selectList(queryWrapper);
        if(dupRs != null && dupRs.size() >= 1) {
            String message = "新增用户失败：身份证重复";
            Exception e = new FebsException(message);
            log.error(message, e);
            throw e;
        }
        Date birthday = getBirthdayFromCardId(rs.getCardId());
        rs.setBirthday(birthday);
        rs.setCreateTime(new Date());
        rs.setCreateUsername(username);
        rs.setCreateUserId(Long.valueOf(userId));
        this.save(rs);
    }

    @Nullable
    private Date getBirthdayFromCardId(String cardId) throws ParseException {
        if(StringUtils.isBlank(cardId)) {
            return null;
        }
        //获取出生日期
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date birthday = null;
        if (cardId.length() == 15) {
            birthday = df.parse("19" + cardId.substring(6, 8) + "-" + cardId.substring(8, 10) + "-" + cardId.substring(10, 12));
        } else if (cardId.length() == 18) {
            birthday = df.parse(cardId.substring(6, 10) + "-" + cardId.substring(10, 12) + "-" + cardId.substring(12, 14));
        }
        return birthday;
    }

    @Override
    public void deleteRs(String[] ids) throws Exception {
        //检查是否是区域管理员
        LambdaQueryWrapper<TAreaManager> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(TAreaManager::getRsId, Arrays.asList(ids));
        int areaManagerCount = tAreaManagerMapper.selectCount(queryWrapper);
        if(areaManagerCount > 0) {
            String message = "删除用户失败：删除用户中包含区域管理员，请先解除区域管理员";
            Exception e = new FebsException(message);
            log.error(message, e);
            throw e;
        }
        //检查是否是商铺经营人产权人
        LambdaQueryWrapper<TShop> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.in(TShop::getOwnerId, Arrays.asList(ids)).or().in(TShop::getOpeId, Arrays.asList(ids));
        int shopPeopleCount = tShopMapper.selectCount(queryWrapper2);
        if(shopPeopleCount > 0) {
            String message = "删除用户失败：删除用户中包含商铺产权人或者商铺经营人，请先解除商铺产权人或者商铺经营人";
            Exception e = new FebsException(message);
            log.error(message, e);
            throw e;
        }
        //删除与住宅关联
        itResidentHouseService.deleteByRsIds(Arrays.asList(ids));
        removeByIds(Arrays.asList(ids));
    }

    @Override
    public void updateRs(TResident rs) throws Exception{
        //获取当前用户
        String token = (String) SecurityUtils.getSubject().getPrincipal();
        String username = "";
        String userId = "";
        if (StringUtils.isNotBlank(token)) {
            username = JWTUtil.getUsername(token);
            userId = JWTUtil.getUserId(token);
        }

        TResident tempArea = getById(rs.getId());
        if(tempArea == null) {
            String message = "更新住户失败：住户不存在";
            Exception e = new FebsException(message);
            log.error(message, e);
            throw e;
        }
        if(this.checkDup(rs.getCardId(), rs.getMobile(), rs.getId())) {
            String message = "更新住户失败：住户编码重复或者住户名称重复";
            Exception e = new FebsException(message);
            log.error(message, e);
            throw e;
        }

        rs.setBirthday(getBirthdayFromCardId(rs.getCardId()));

        // 更新住户信息
        UpdateWrapper<TResident> upWrp = new UpdateWrapper<>();
        upWrp.set("RS_NAME", rs.getRsName());
        upWrp.set("CARD_ID", rs.getCardId());
        upWrp.set("BIRTHDAY", rs.getBirthday());
        upWrp.set("SSEX", rs.getSsex());
        upWrp.set("NATION", rs.getNation());
        upWrp.set("MOBILE", rs.getMobile());
        upWrp.set("POLITICS", rs.getPolitics());
        upWrp.set("POLITICS_BRANCH", rs.getPoliticsBranch());
        upWrp.set("CENSUS_ADR", rs.getCensusAdr());
        upWrp.set("CULTURE", rs.getCulture());
        upWrp.set("WORK_UNIT", rs.getWorkUnit());
        upWrp.set("WORK_ADR", rs.getWorkAdr());
        upWrp.set("INCOME", rs.getIncome());
        upWrp.set("STATUS", rs.getStatus());
        upWrp.set("MODIFY_TIME", new Date());
        upWrp.set("MODIFY_USERNAME", username);
        upWrp.set("MODIFY_USER_ID", userId);
        upWrp.eq("ID",rs.getId());
        this.baseMapper.update(null, upWrp);

        //更新商铺产权人和经营人信息
        LambdaQueryWrapper<TShop> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.eq(TShop::getOwnerId, rs.getId()).or().eq(TShop::getOpeId, rs.getId());
        int ownOrOpeCount = tShopMapper.selectCount(queryWrapper2);
        if(ownOrOpeCount > 0) {
            tShopMapper.updateOwnerName(rs.getId(), rs.getRsName());
            tShopMapper.updateOpeName(rs.getId(), rs.getRsName());
        }
    }

    @Override
    public int countResidents(List<TResident> rsIds) {
        List<Long> ids = new ArrayList<>();
        rsIds.forEach(f -> {
            if(null != f.getId()) {
                ids.add(f.getId());
            }
        });

        int ret = 0;
        if(ids.size() > 0) {
            LambdaQueryWrapper<TResident> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(TResident::getId, ids);
            ret = this.baseMapper.selectCount(queryWrapper);
        }
        return ret;
    }

    @Override
    public List<TResident> findResidents(TResident rs) {
        try {
            LambdaQueryWrapper<TResident> queryWrapper = new LambdaQueryWrapper<>();
            if(StringUtils.isNotBlank(rs.getMobile())) {
                queryWrapper.eq(TResident::getMobile, rs.getMobile());
            }
            if(StringUtils.isNotBlank(rs.getCardId())) {
                queryWrapper.eq(TResident::getCardId, rs.getCardId());
            }
            if(StringUtils.isNotBlank(rs.getRsName())) {
                queryWrapper.eq(TResident::getRsName, rs.getRsName());
            }
            return this.baseMapper.selectList(queryWrapper);
        } catch (Exception e) {
            log.error("获取住户信息失败", e);
            return null;
        }
    }

    @Override
    public List<Map<String, Object>> importRs(List<Map<String, Object>> successList) throws Exception {
        //获取当前用户
        String token = (String) SecurityUtils.getSubject().getPrincipal();
        String username = "";
        String userId = "";
        if (StringUtils.isNotBlank(token)) {
            username = JWTUtil.getUsername(token);
            userId = JWTUtil.getUserId(token);
        }

        List<Map<String, Object>> errList = new ArrayList<>();
        List<TResidentImportVO> residentImportVOS = new ArrayList<>();

        List<Integer> errRow = new ArrayList<>();
        List<Integer> handledRow = new ArrayList<>();
        for(Map<String, Object> scIt: successList) {
            TResidentExcelVO entity = (TResidentExcelVO) scIt.get("entity");
            int sheetIndex = (int) scIt.get("sheetIndex");
            int rowIndex = (int) scIt.get("rowIndex");

            if(!errRow.isEmpty() && errRow.contains(rowIndex)) {
                continue;
            }

            if(!handledRow.isEmpty() && handledRow.contains(rowIndex)) {
                continue;
            }

            //1.收集同一户成员
            List<Map<String, Object>> dupItems = successList.stream().filter(f ->
                    ((int) f.get("sheetIndex") != sheetIndex) &&
                            ((int) f.get("rowIndex") != rowIndex) && (!errRow.contains((int) f.get("rowIndex"))) &&
                            (((TResidentExcelVO) f.get("entity")).getHouseCode().equals(entity.getHouseCode()))
            ).collect(Collectors.toList());

            //2.1身份证号是否与表格内人员重复
            List<Map<String, Object>> dupCarIds = successList.stream().filter(f ->
                    ((int) f.get("sheetIndex") != sheetIndex) &&
                            ((int) f.get("rowIndex") != rowIndex) &&
                            (((TResidentExcelVO) f.get("entity")).getCardId().equals(entity.getCardId()))
            ).collect(Collectors.toList());
            if(dupCarIds.size() > 1) {
                errRow.add(rowIndex);

                ArrayList<ExcelErrorField> excelErrorFields = new ArrayList<>();
                ExcelErrorField excelErrorField = new ExcelErrorField();
                excelErrorField.setErrorMessage("与表内其他住户的身份证信息重复");
                excelErrorFields.add(excelErrorField);
                errList.add(
                        ImmutableMap.of("sheetIndex", sheetIndex,//
                                "rowIndex", rowIndex,//
                                "errorFields", excelErrorFields));
                continue;
            }
            //同一户人员身份证是否与表格内人员重复
            for (Map<String, Object> dupItem : dupItems) {
                if(errRow.contains((int) dupItem.get("rowIndex"))) {
                    continue;
                }

                List<Map<String, Object>> dupCarIdsOfdupItem = successList.stream().filter(f ->
                        ((int) f.get("sheetIndex") != (int) dupItem.get("sheetIndex")) &&
                                ((int) f.get("rowIndex") != (int) dupItem.get("rowIndex")) &&
                                (((TResidentExcelVO) f.get("entity")).getCardId().equals(((TResidentExcelVO) dupItem.get("entity")).getCardId()))
                ).collect(Collectors.toList());
                if(dupCarIdsOfdupItem.size() > 1) {
                    errRow.add((int) dupItem.get("rowIndex"));

                    ArrayList<ExcelErrorField> excelErrorFields = new ArrayList<>();
                    ExcelErrorField excelErrorField = new ExcelErrorField();
                    excelErrorField.setErrorMessage("与表内其他住户的身份证信息重复");
                    excelErrorFields.add(excelErrorField);
                    errList.add(
                            ImmutableMap.of("sheetIndex", (int) dupItem.get("sheetIndex"),//
                                    "rowIndex", (int) dupItem.get("rowIndex"),//
                                    "errorFields", excelErrorFields));
                }
            }
            //2.2身份证号是否与数据库人员重复
            int cardIdCount = tResidentMapper.countCardId(entity.getCardId());
            if(cardIdCount > 0) {
                errRow.add(rowIndex);

                ArrayList<ExcelErrorField> excelErrorFields = new ArrayList<>();
                ExcelErrorField excelErrorField = new ExcelErrorField();
                excelErrorField.setErrorMessage("与已存在住户的身份证信息重复");
                excelErrorFields.add(excelErrorField);
                errList.add(
                        ImmutableMap.of("sheetIndex", sheetIndex,//
                                "rowIndex", rowIndex,//
                                "errorFields", excelErrorFields));
                continue;
            }
            //同一户人员身份证是否与现有人员重复
            for (Map<String, Object> dupItem : dupItems) {
                if(errRow.contains((int) dupItem.get("rowIndex"))) {
                    continue;
                }

                String dupItemCardId = ((TResidentExcelVO) dupItem.get("entity")).getCardId();
                int cardIdOfDupItemCount = tResidentMapper.countCardId(dupItemCardId);

                if(cardIdOfDupItemCount > 1) {
                    errRow.add((int) dupItem.get("rowIndex"));

                    ArrayList<ExcelErrorField> excelErrorFields = new ArrayList<>();
                    ExcelErrorField excelErrorField = new ExcelErrorField();
                    excelErrorField.setErrorMessage("与表内其他住户的身份证信息重复");
                    excelErrorFields.add(excelErrorField);
                    errList.add(
                            ImmutableMap.of("sheetIndex", (int) dupItem.get("sheetIndex"),//
                                    "rowIndex", (int) dupItem.get("rowIndex"),//
                                    "errorFields", excelErrorFields));
                }
            }

            //1.2是否存在多户主或者无户主
            //数据库里存在的户主
            List<TResidentHouse> tResidentHouses = tempInfoManager.getAllHouseOwner();
            boolean hasHouseOwner = tResidentHouses.stream().anyMatch(f -> f.getHouseCode().equals(entity.getHouseCode()));

            List<Map<String, Object>> dupHouseOwners = dupItems.stream().filter(f ->
                            (((TResidentExcelVO) f.get("entity")).getRelation().equals("户主"))
            ).collect(Collectors.toList());
            //无户主
            if(dupHouseOwners.isEmpty() && !"户主".equals(entity.getRelation()) && !hasHouseOwner) {
                errRow.add(rowIndex);
                dupItems.forEach(f -> errRow.add((int) f.get("rowIndex")));

                ArrayList<ExcelErrorField> excelErrorFields = new ArrayList<>();
                ExcelErrorField excelErrorField = new ExcelErrorField();
                excelErrorField.setErrorMessage("住宅编码：" + entity.getHouseCode() + "无户主");
                excelErrorFields.add(excelErrorField);
                errList.add(
                        ImmutableMap.of("sheetIndex", sheetIndex,//
                                "rowIndex", rowIndex,//
                                "errorFields", excelErrorFields));
                continue;
            }
            //多户主
            if((!dupHouseOwners.isEmpty() && dupHouseOwners.size() > 1) ||
                    (dupHouseOwners.size() == 1 && "户主".equals(entity.getRelation())) ||
                    (dupHouseOwners.size() == 1 && hasHouseOwner) ||
                    ("户主".equals(entity.getRelation()) && hasHouseOwner)) {
                errRow.add(rowIndex);
                dupItems.forEach(f -> errRow.add((int) f.get("rowIndex")));

                ArrayList<ExcelErrorField> excelErrorFields = new ArrayList<>();
                ExcelErrorField excelErrorField = new ExcelErrorField();
                excelErrorField.setErrorMessage("住宅编码：" + entity.getHouseCode() + "存在多户主");
                excelErrorFields.add(excelErrorField);
                errList.add(
                        ImmutableMap.of("sheetIndex", sheetIndex,//
                                "rowIndex", rowIndex,//
                                "errorFields", excelErrorFields));
                continue;
            }

            //1.4户主住房情况是否未填写
            String houseStatus = null;
            if(!hasHouseOwner) {
                if("户主".equals(entity.getRelation())) {
                    if(StringUtils.isBlank(entity.getHouseStatus())) {
                        errRow.add(rowIndex);
                        dupItems.forEach(f -> errRow.add((int) f.get("rowIndex")));

                        ArrayList<ExcelErrorField> excelErrorFields = new ArrayList<>();
                        ExcelErrorField excelErrorField = new ExcelErrorField();
                        excelErrorField.setErrorMessage("住宅编码：" + entity.getHouseCode() + "住房情况未填写");
                        excelErrorFields.add(excelErrorField);
                        errList.add(
                                ImmutableMap.of("sheetIndex", sheetIndex,//
                                        "rowIndex", rowIndex,//
                                        "errorFields", excelErrorFields));
                        continue;
                    }
                    houseStatus = entity.getHouseStatus();
                } else {
                    TResidentExcelVO dupHouseOwnerTmp = (TResidentExcelVO) dupHouseOwners.get(0).get("entity");
                    if(StringUtils.isBlank(dupHouseOwnerTmp.getHouseStatus())) {
                        errRow.add(rowIndex);
                        dupItems.forEach(f -> errRow.add((int) f.get("rowIndex")));

                        ArrayList<ExcelErrorField> excelErrorFields = new ArrayList<>();
                        ExcelErrorField excelErrorField = new ExcelErrorField();
                        excelErrorField.setErrorMessage("住宅编码：" + entity.getHouseCode() + "住房情况未填写");
                        excelErrorFields.add(excelErrorField);
                        errList.add(
                                ImmutableMap.of("sheetIndex", sheetIndex,//
                                        "rowIndex", rowIndex,//
                                        "errorFields", excelErrorFields));
                        continue;
                    }
                    houseStatus = dupHouseOwnerTmp.getHouseStatus();
                }
            }

            //3.所属片区是否存在
            List<THouse> houseCodes = tempInfoManager.getAllHouseCode();
            boolean hasHouse = houseCodes.stream().anyMatch(f -> f.getHouseCode().equals(entity.getHouseCode()));
            Area houseArea = null;
            if(!hasHouse) {
                List<Area> areas = tempInfoManager.getAllArea();
                List<Area> aTmp = areas.stream().filter(f -> f.getAreaName().equals(entity.getAreaName())).collect(Collectors.toList());
                if(aTmp.size() > 0) {
                    entity.setAreaId(aTmp.get(0).getAreaId());
                    houseArea = aTmp.get(0);
                } else {
                    errRow.add(rowIndex);
                    dupItems.forEach(f -> errRow.add((int) f.get("rowIndex")));

                    ArrayList<ExcelErrorField> excelErrorFields = new ArrayList<>();
                    ExcelErrorField excelErrorField = new ExcelErrorField();
                    excelErrorField.setErrorMessage("所属四级片区不存在");
                    excelErrorFields.add(excelErrorField);
                    errList.add(
                            ImmutableMap.of("sheetIndex", sheetIndex,//
                                    "rowIndex", rowIndex,//
                                    "errorFields", excelErrorFields));
                    continue;
                }
                //同一户片区是否一致
                for (Map<String, Object> dupItem : dupItems) {
                    if(errRow.contains((int) dupItem.get("rowIndex"))) {
                        continue;
                    }

                    String dupItemAreaName = ((TResidentExcelVO) dupItem.get("entity")).getAreaName();
                    if(!aTmp.get(0).getAreaName().equals(dupItemAreaName)) {
                        errRow.add((int) dupItem.get("rowIndex"));

                        ArrayList<ExcelErrorField> excelErrorFields = new ArrayList<>();
                        ExcelErrorField excelErrorField = new ExcelErrorField();
                        excelErrorField.setErrorMessage("同一户人家所属片区不一致");
                        excelErrorFields.add(excelErrorField);
                        errList.add(
                                ImmutableMap.of("sheetIndex", (int) dupItem.get("sheetIndex"),//
                                        "rowIndex", (int) dupItem.get("rowIndex"),//
                                        "errorFields", excelErrorFields));
                    } else {
                        ((TResidentExcelVO) dupItem.get("entity")).setAreaId(aTmp.get(0).getAreaId());
                    }
                }
            }

            TResidentImportVO tResidentTmp = new TResidentImportVO();
            //组装住宅信息
            THouse houseOwner = null;
            if(!hasHouse) {
                THouse tHouse = new THouse();
                tHouse.setHouseCode(entity.getHouseCode());
                tHouse.setHouseAdr(entity.getHouseAdr());
                tHouse.setAreaId(houseArea.getAreaId());
                tHouse.setStatus(houseStatus);
                tHouse.setCreateTime(new Date());
                tHouse.setCreateUserId(Long.valueOf(userId));
                tHouse.setCreateUsername(username);
                houseOwner = tHouse;
            } else {
                houseOwner = houseCodes.stream().filter(f -> f.getHouseCode().equals(entity.getHouseCode())).collect(Collectors.toList()).get(0);
            }
            tResidentTmp.setTHouse(houseOwner);

            //组装住户信息
            List<TResidentVO> rsList = new ArrayList<>();
            TResidentVO rsTemp = new TResidentVO();
            rsTemp.setRsName(entity.getRsName());
            rsTemp.setCardId(entity.getCardId());
            rsTemp.setBirthday(getBirthdayFromCardId(entity.getCardId()));
            rsTemp.setSsex(entity.getSex());
            rsTemp.setNation(entity.getNation());
            rsTemp.setMobile(entity.getMobile());
            rsTemp.setPolitics(entity.getPolitics());
            rsTemp.setPoliticsBranch(entity.getPoliticsBranch());
            rsTemp.setCensusAdr(entity.getCensusAdr());
            rsTemp.setCulture(entity.getCulture());
            rsTemp.setWorkUnit(entity.getWorkUnit());
            rsTemp.setWorkAdr(entity.getWorkAdr());
            rsTemp.setIncome(entity.getIncome());
            rsTemp.setStatus(entity.getStatus());
            rsTemp.setRelation(entity.getRelation());
            rsTemp.setCreateTime(new Date());
            rsTemp.setCreateUserId(Long.valueOf(userId));
            rsTemp.setCreateUsername(username);
            rsList.add(rsTemp);
            //加入已处理列表
            handledRow.add(rowIndex);
            //同一户组装
            for (Map<String, Object> dupItem : dupItems) {
                if(errRow.contains((int) dupItem.get("rowIndex"))) {
                    continue;
                }
                TResidentVO rsDupTemp = new TResidentVO();
                TResidentExcelVO dupEntity = (TResidentExcelVO) dupItem.get("entity");
                rsDupTemp.setRsName(dupEntity.getRsName());
                rsDupTemp.setCardId(dupEntity.getCardId());
                rsDupTemp.setBirthday(getBirthdayFromCardId(dupEntity.getCardId()));
                rsDupTemp.setSsex(dupEntity.getSex());
                rsDupTemp.setNation(dupEntity.getNation());
                rsDupTemp.setMobile(dupEntity.getMobile());
                rsDupTemp.setPolitics(dupEntity.getPolitics());
                rsDupTemp.setPoliticsBranch(dupEntity.getPoliticsBranch());
                rsDupTemp.setCensusAdr(dupEntity.getCensusAdr());
                rsDupTemp.setCulture(dupEntity.getCulture());
                rsDupTemp.setWorkUnit(dupEntity.getWorkUnit());
                rsDupTemp.setWorkAdr(dupEntity.getWorkAdr());
                rsDupTemp.setIncome(dupEntity.getIncome());
                rsDupTemp.setStatus(dupEntity.getStatus());
                rsDupTemp.setRelation(entity.getRelation());
                rsDupTemp.setCreateTime(new Date());
                rsDupTemp.setCreateUserId(Long.valueOf(userId));
                rsDupTemp.setCreateUsername(username);
                rsList.add(rsTemp);
                //加入已处理列表
                handledRow.add((int) dupItem.get("rowIndex"));
            }
            tResidentTmp.setRs(rsList);
            residentImportVOS.add(tResidentTmp);
        }

        if(errList.isEmpty() && !residentImportVOS.isEmpty()) {
            try {
                insertRsListWithNoCheck(residentImportVOS);
            } catch (Exception fe) {
                String message = "导入住户失败：" + fe.getMessage();
                Exception e = new FebsException(message);
                log.error(message, e);
                throw e;
            }
        }

        return errList;
    }

    private void insertRsListWithNoCheck(List<TResidentImportVO> residentImportVOS) throws Exception {
        //获取当前用户
        String token = (String) SecurityUtils.getSubject().getPrincipal();
        String username = "";
        String userId = "";
        if (StringUtils.isNotBlank(token)) {
            username = JWTUtil.getUsername(token);
            userId = JWTUtil.getUserId(token);
        }

        for (TResidentImportVO residentImportVO : residentImportVOS) {
            //插入住宅
            THouse tHouse = residentImportVO.getTHouse();
            if(null == tHouse.getId()) {
                tHouseMapper.insertDetail(tHouse);
            }

            if(null == tHouse.getId()) {
                String message = "导入住户失败：住宅创建失败";
                Exception e = new FebsException(message);
                log.error(message, e);
                throw e;
            }

            //插入住户
            List<TResidentVO> rsList = residentImportVO.getRs();
            this.baseMapper.insertList(rsList);

            //插入关系
            List<TResidentHouse> rsHouseList = new ArrayList<>();
            for (TResidentVO tResident : rsList) {
                TResidentHouse rsHouseTmp = new TResidentHouse();
                rsHouseTmp.setHouseId(tHouse.getId());
                rsHouseTmp.setHouseCode(tHouse.getHouseCode());
                rsHouseTmp.setRelation(tResident.getRelation());
                rsHouseTmp.setRsId(tResident.getId());
                rsHouseTmp.setCreateTime(new Date());
                rsHouseTmp.setCreateUserId(Long.valueOf(userId));
                rsHouseTmp.setCreateUsername(username);
                rsHouseList.add(rsHouseTmp);
            }
            tResidentHouseMapper.insertList(rsHouseList);
        }
    }

    private boolean checkDup(String cardId, String mobile, Long id) {
        QueryWrapper<TResident> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().ne(TResident::getId, id).eq(TResident::getCardId, cardId);
        if(StringUtils.isNotBlank(mobile)) {
            queryWrapper.or(qw -> qw.lambda().ne(TResident::getId, id).eq(TResident::getMobile, mobile));
        }
        List<TResident> ret = this.baseMapper.selectList(queryWrapper);
        return (null != ret && ret.size() > 1);
    }
}
